<template>
  <div class="personal-data">
    <div class="top">个人资料</div>
    <div class="bottom">
      <div class="bottom-left">
        <el-form ref="form" :model="form" label-width="80px" :rules="rules">
          <el-form-item label="用户名" prop="username">
            <div class="username-wrapper">
              <el-input
                v-model="form.username"
                maxlength="10"
                placeholder="请输入用户名"
              >
              </el-input>
              <div class="char-count">{{ form.username.length }}/10</div>
            </div>
          </el-form-item>
          <el-form-item label="个人介绍" prop="intro">
            <div class="intro-wrapper">
              <el-input
                type="textarea"
                :autosize="{ minRows: 3, maxRows: 5 }"
                placeholder="请输入个人介绍"
                v-model="form.intro"
                maxlength="100"
              >
              </el-input>
              <div class="char-count">{{ form.intro.length }}/100</div>
            </div>
          </el-form-item>
          <el-form-item label="兴趣标签" prop="tags">
            <div class="tags">
              <span v-if="form.selectedTags.length === 0" style="color: #606266"
                >请从下列标签中至少选择一项</span
              >
              <div v-else class="select-tags">
                <el-tag
                  v-for="item in form.selectedTags"
                  :key="item.interestId"
                  effect="plain"
                  @close="reduce(item)"
                  closable
                >
                  {{ item.tagsName }}
                </el-tag>
              </div>
              <div class="tag-data" v-loading="loading">
                <div
                  class="tag-item"
                  :class="{ select: isSelected(item.interestId) }"
                  @click="selectTag(item)"
                  v-for="item in tags"
                  :key="item.interestId"
                >
                  {{ item.tagsName }}
                </div>
              </div>
            </div>
          </el-form-item>
          <el-form-item>
            <el-button
              type="primary"
              @click="onSubmit"
              v-loading="saveLoading"
              :disabled="saveLoading"
              element-loading-spinner="el-icon-loading"
              element-loading-background="rgba(100, 0, 0, -1)"
              >保存</el-button
            >
            <el-button @click="resetForm" :disabled="saveLoading"
              >重置</el-button
            >
          </el-form-item>
        </el-form>
      </div>
      <div class="bottom-right">
        <el-upload
          class="avatar-uploader"
          action="/api/upload/file"
          name="image"
          :show-file-list="false"
          :on-change="changeFile"
          :on-success="handleAvatarSuccess"
          :auto-upload="false"
          ref="upload"
        >
          <img v-if="form.imgUrl" :src="form.imgUrl" class="avatar" />
          <i v-else class="el-icon-plus avatar-uploader-icon"></i>
        </el-upload>
        <div class="avatar-desc">上传头像</div>
        <div class="info">
          <span>格式：支持JPG、PNG</span><br />
          <span>大小：2M以内</span>
        </div>
      </div>
    </div>
  </div>
</template>

<script>
import { getUserId } from "../../../utils/auth";
import {
  getTagsData,
  getUserData,
  updateUserInfo,
} from "../../../api/personal";
export default {
  data() {
    return {
      form: {
        username: "",
        intro: "",
        imgUrl: "",
        // 用户选择的标签
        selectedTags: [],
      },
      // 不知道为什么上传的文件拿回来不能及时更新，所以用这个变量保存一下
      selectImgUrl: "",
      rules: {
        username: [
          { required: true, message: "请输入用户名", trigger: "blur" },
          {
            min: 3,
            max: 10,
            message: "长度在 3 到 10 个字符",
            trigger: "blur",
          },
        ],
        intro: [{ required: true, message: "请输入个人介绍", trigger: "blur" }],
        tags: [
          {
            required: true,
            validator: (rule, value, callback) => {
              if (this.form.selectedTags.length === 0) {
                callback(new Error("请选择兴趣标签"));
              } else {
                callback();
              }
            },
            trigger: "change",
          },
        ],
      },
      // 供用户选择兴趣标签数据
      tags: [],
      // 标签加载的loading
      loading: true,
      // 保存按钮loading
      saveLoading: false,
      // 文件上传是否结束
      isUploadSuccess: false,
      isSelectFile: false,
    };
  },
  methods: {
    onSubmit() {
      this.$refs.form.validate((valid) => {
        if (valid) {
          if (!this.isSelectFile) {
            this.isUploadSuccess = true;
          } else {
            this.$refs.upload.submit();
          }
          this.saveLoading = true;
          const interval = setInterval(() => {
            if (this.isUploadSuccess) {
              clearInterval(interval);
              const updateForm = {
                userId: getUserId(),
                username: this.form.username,
                intro: this.form.intro,
                imgUrl: this.isSelectFile
                  ? this.selectImgUrl
                  : this.form.imgUrl,
                interestIds: this.form.selectedTags.map(
                  (tag) => tag.interestId
                ),
              };
              updateUserInfo(updateForm).then((res) => {
                if (res.data.code === 1) {
                  this.$notify({
                    title: "成功",
                    message: "保存成功",
                    type: "success",
                  });
                  this.saveLoading = false;
                  this.getUserData();
                } else {
                  this.$message.error("网络错误");
                }
              });
            }
          });
        } else {
          console.log("error submit!!");
          return false;
        }
      });
    },
    // 重置表单验证
    resetForm() {
      this.$refs.form.resetFields(); // 重置表单字段和验证结果
      this.form.selectedTags = [];
    },
    // 获取用户兴趣标签数据
    getTagsData() {
      this.loading = true;
      getTagsData().then((res) => {
        if (res.data.code === 1) {
          this.tags = res.data.data;
          this.loading = false;
        } else {
          this.$message.error("网络错误");
        }
      });
    },
    // 选择标签
    selectTag(item) {
      if (!this.isSelected(item.interestId)) {
        this.form.selectedTags.push(item);
      } else {
        this.reduce(item);
      }
      this.$nextTick(() => {
        this.$refs.form.validateField("tags");
      });
    },
    // 判断选择的标签是否已经选择辅助函数
    isSelected(interestId) {
      return this.form.selectedTags.some(
        (tag) => tag.interestId === interestId
      );
    },
    // 减少标签
    reduce(item) {
      const index = this.form.selectedTags.findIndex(
        (tag) => tag.interestId === item.interestId
      );
      if (index !== -1) {
        this.form.selectedTags.splice(index, 1);
      }
      this.$nextTick(() => {
        this.$refs.form.validateField("tags");
      });
    },
    // 选择文件
    changeFile(file) {
      this.isSelectFile = true;
      const isJPGorPNG =
        file.raw.type === "image/jpeg" || file.raw.type === "image/png";
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isJPGorPNG) {
        this.$message.error("上传头像图片只能是 JPG 或 PNG 格式!");
        return false;
      }
      if (!isLt2M) {
        this.$message.error("上传头像图片大小不能超过 2MB!");
        return false;
      }
      this.previewImage(file);
    },
    // 回显图片
    previewImage(file) {
      const reader = new FileReader();
      reader.onload = (e) => {
        this.form.imgUrl = e.target.result; // 显示预览
      };
      reader.readAsDataURL(file.raw); // 确保传递 file.raw 而不是 file
    },
    // 上传成功
    handleAvatarSuccess(res) {
      this.selectImgUrl = res.data;
      this.isUploadSuccess = true;
    },
    // 获取用户信息
    getUserData() {
      getUserData(getUserId()).then((res) => {
        if (res.data.code === 1) {
          this.form.username = res.data.data.username;
          this.form.intro = res.data.data.intro;
          this.form.imgUrl = res.data.data.imgUrl;
          this.form.selectedTags = res.data.data.userTags;
        } else {
          this.$message.error("网络错误");
        }
      });
    },
  },
  mounted() {
    this.getUserData();
    this.getTagsData();
  },
  created() {},
};
</script>

<style lang="less" scoped>
@import url("../../../assets/ElementUIStyle/el-button.css");
.personal-data {
  .top {
    font-size: 20px;
    font-weight: 700;
    padding-bottom: 15px;
    border-bottom: 1px solid #e4e6eb;
  }
  .bottom {
    margin-top: 20px;
    display: flex;
    justify-content: space-between;
    gap: 20px;
    .bottom-left {
      width: 70%;
      .username-wrapper {
        position: relative;
        width: 100%;
        .el-input {
          width: 100%; /* 定义输入框的宽度 */
        }
        .char-count {
          position: absolute;
          right: 5px;
          top: 52%;
          transform: translateY(-50%);
          padding: 0 5px;
          color: #9399a6;
          font-size: 12px;
        }
      }
      .intro-wrapper {
        position: relative;
        width: 100%;
        .el-input {
          width: 100%; /* 定义输入框的宽度 */
          resize: none;
        }
        .char-count {
          position: absolute;
          right: 5px;
          top: 78%;
          transform: translateY(-50%);
          padding: 0 5px;
          color: #9399a6;
          font-size: 12px;
        }
      }
      .tags {
        .select-tags {
          margin-top: 10px;
          margin-bottom: 15px;
          display: flex;
          flex-wrap: wrap;
          gap: 10px;
          /deep/ .el-tag {
            border-radius: 0 !important;
            line-height: 25px !important;
            height: 25px !important;
          }
        }
        .tag-data {
          min-height: 100px;
          border-radius: 4px;
          border: 1px solid #e4e6eb;
          padding: 15px;
          display: flex;
          flex-wrap: wrap;
          gap: 10px;
          .tag-item {
            cursor: pointer;
            line-height: 20px;
            height: 20px;
            padding: 5px;
            color: #8a919f;
            font-size: 12px;
            background-color: #f2f3f5;
            border-radius: 4px;
            &.select {
              color: #1e80ff;
              background-color: #eaf2ff;
            }
          }
        }
      }
    }
    .bottom-right {
      width: 20%;
      margin-right: 20px;
      display: flex;
      flex-direction: column;
      align-items: center;
      gap: 20px;
      img {
        border-radius: 50%;
        height: 100px;
        width: 100px;
        user-select: none;
        cursor: pointer;
      }
      .avatar-desc {
        font-size: 14px;
        color: #252933;
      }
      .info {
        span {
          line-height: 20px;
        }
        font-size: 12px;
        color: #8a919f;
      }
    }
  }
}
</style>

<style scoped>
::v-deep .el-textarea__inner {
  resize: none;
}
::v-deep .el-upload {
  border: 1px dashed #d9d9d9 !important;
  border-radius: 50% !important;
  cursor: pointer !important;
  position: relative !important;
  overflow: hidden !important;
}
::v-deep .avatar-uploader .el-upload:hover {
  border-color: #409eff !important;
}
.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 100px;
  height: 100px;
  line-height: 100px;
  text-align: center;
}
.avatar {
  width: 100px;
  height: 100px;
  display: block;
}
::v-deep .el-loading-spinner {
  top: 100% !important;
}
::v-deep .el-loading-spinner i {
  color: #0001ff;
}
</style>